package com.udaos.modules.enroll.services;

import java.io.IOException;
import java.util.Date;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;

import com.udaos.common.base.AppException;
import com.udaos.common.base.Result;
import com.udaos.common.base.Service;
import com.udaos.common.util.DateUtil;
import com.udaos.common.util.StringUtil;
import com.udaos.models.account.Ud_account;
import com.udaos.models.card.Ud_wx_card;
import com.udaos.models.enroll.Ud_enroll;
import com.udaos.models.physical.Ud_physical_code;
import com.udaos.models.student.Ud_student;
import com.udaos.models.sys.Sys_user;
import com.udaos.models.wx.Wx_config;
import com.udaos.modules.account.services.UdAccountService;
import com.udaos.modules.card.services.UdWxCardService;
import com.udaos.modules.customer.services.UdWxUserService;
import com.udaos.modules.enroll.utils.AcountConfigUtils;
import com.udaos.modules.enroll.vo.WxConfig;
import com.udaos.modules.physical.services.UdPhysicalCodeService;
import com.udaos.modules.sales.services.UdSalesService;
import com.udaos.modules.student.services.UdStudentService;
import com.udaos.modules.wx.services.ApiWxTemplateService;
import com.udaos.modules.wx.services.WxConfigService;

import me.chanjar.weixin.mp.api.WxMpConfigStorage;
import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.bean.result.WxMpPayResult;

/**
 * 报名Service
 * @author mutaotao
 *
 */
@IocBean(args = { "refer:dao" })
public class UdEnrollService extends Service<Ud_enroll>{
	
	@Inject
	private UdPhysicalCodeService codeService;
	@Inject
	private ApiWxTemplateService templateService;
	@Inject
	private UdWxUserService udWxUserService;
	@Inject
	private UdAccountService accountService;
	@Inject
	private WxConfigService wxConfigService;
	@Inject
	private UdSalesService salesService;
	@Inject
	private UdStudentService studentService;
	@Inject
	private UdWxCardService udWxCardService;

	public UdEnrollService(Dao dao) {
		super(dao);
	}

	/**
	 * 发送体检码
	 * @param enroll
	 * @throws AppException 
	 */
	public void sendCode(Ud_enroll enroll) throws AppException {
		String codeStr="";
		//判断是否已经发送
		Ud_physical_code code=codeService.fetch(Cnd.where("bill_id", "=", enroll.getId()).and("bill_type", "=", "enroll"));
		if(null ==code){
			//获取新的体检码
			codeStr=codeService.getCode();
			if(null == codeStr){
				throw new AppException("获取体检码失败，请查看是否存在有效的体检码！");
			}
		}else{
			codeStr=code.getSn()+"-"+code.getCode();
		}
		//获取其报名公众号信息,根据openId获取其所属微信平台
		String appid=udWxUserService.fetch(enroll.getUser_id()).getAppid();
		//发送模板消息
		boolean b=templateService.sendPhysicalTemplate(appid, enroll.getUser_id(), codeStr);
		if(b){
			Ud_physical_code pCode =codeService.fetch(Cnd.where("sn", "=", codeStr.split("-")[0]));
			pCode.setState(1);
			pCode.setBill_type("enroll");
			pCode.setBill_id(enroll.getId());
			pCode.setDrawat((int)(System.currentTimeMillis()/1000));
			codeService.update(pCode);
		}
		
	}

	/**
	 * 判断是否已经付款
	 * @param enrollId
	 * @throws IOException 
	 */
	public Result checkIsEnroll(String enrollId) throws IOException {
		Ud_enroll enroll = this.fetch(enrollId);
		// 获取支付账户微信号
		Ud_account account = accountService.fetch(enroll.getAccount_id());
		WxConfig config = AcountConfigUtils.getWxConfig(account.getConfig());
		WxMpPayResult payResult = this.wxPayQueryOrder(config.getAppId(), null, enroll.getBill_no());
		if ("SUCCESS".equals(payResult.getReturn_code()) && "SUCCESS".equals(payResult.getResult_code()) &&  "SUCCESS".equals(payResult.getTrade_state())) {
			enroll.setPay_flag(true);
			enroll.setState(1);
			enroll.setPay_flag(true);
			enroll.setPay_time(DateUtil.getTime(payResult.getTime_end(), "yyyyMMddHHmmss"));
			enroll.setPay_trans_id(payResult.getTransaction_id());
			enroll.setPay_way("WX_JSAPI");
			enroll.setState(1);
			enroll.setMoney(enroll.getPrice()-enroll.getDiscount());
			enroll.setOpAt((int)(System.currentTimeMillis()/1000));
			this.updateIgnoreNull(enroll);
			
			//判断是否含有推荐码，有的话进行奖励
			salesService.reward(enroll.getReference_code(),enroll.getCompany_id());
			// 生成学员档案
			Ud_student student = new Ud_student();
			student.setCustomer_id(enroll.getCustomer_id());
			student.setState(0);
			student.setEnroll_state(1);
			student.setEnroll_time(enroll.getPay_time());
			student.setCompany_id(enroll.getCompany_id());
			student.setProgress(0);
			student.setEnroll_progress(2);
			student.setName(enroll.getName());
			student.setEnroll_id(enroll.getId());
			student.setMobile(enroll.getMobile());
			student.setSubject1_state(-1);
			student.setSubject2_state(-1);
			student.setSubject3_state(-1);
			
			studentService.insert(student);
			// 对卡券进行核销
			if (!StringUtil.isNullOrEmpty(enroll.getCard_id())
					&& !StringUtil.isNullOrEmpty(enroll.getCard_code())) {
				Ud_wx_card cardInfo=udWxCardService.fetch(Cnd.where("card_id", "=", enroll.getCard_id()));
				if(null != cardInfo){
					enroll.setDiscount(cardInfo.getCard_fee());
				}
				udWxCardService.consume(config.getAppId(),enroll.getUser_id(),enroll.getCard_id(),enroll.getCard_code());
			}
			// 发送体检码（微信模板，短信）
			String code=codeService.getCode();
			if(null ==code){
				code="体检码获取失败，请联系平台客服索取体检码！";
			}
			boolean b=templateService.sendTaskRemind(config.getAppId(), "oqDfiw8sciEFi5ch_zs_89TDeGWM", null, "新学员报名通知", "学员报名", enroll.getName()+"完成在线报名,支付金额："+enroll.getMoney()+"元。联系电话："+enroll.getMobile()+"请及时跟进", DateUtil.format(new Date(), "yyyy-MM-dd HH:mm")+"", "请尽快处理");
			boolean c=templateService.sendPhysicalTemplate(config.getAppId(), enroll.getUser_id(), code);
			if(c){
				Ud_physical_code pCode =codeService.fetch(Cnd.where("sn", "=", code.split("-")[0]));
				pCode.setState(1);
				pCode.setBill_type("enroll");
				pCode.setBill_id(enroll.getId());
				pCode.setDrawat((int)(System.currentTimeMillis()/1000));
				codeService.update(pCode);
			}
			
			
			
			return Result.success("已缴费,并将材料补全");
		}else{
			return Result.error("未交费");
		}
		
	}
	/**
		 * 查询支付结果
		 * @param wxid
		 * @param transaction_id
		 * @param out_trade_no
		 * @return
		 * @throws IOException
		 */
		public WxMpPayResult wxPayQueryOrder(String wxid, String transaction_id, String out_trade_no) throws IOException {
			// 获取微信相关信息
			Subject subject = SecurityUtils.getSubject();
			Sys_user user = (Sys_user) subject.getPrincipal();
			Wx_config config=wxConfigService.fetch(Cnd.where("company_id", "=", user.getUnit().getCompany_id()));
			WxMpService wxMpService=getWxMpService(config.getId());
			WxMpPayResult payResult = wxMpService.getPayService().getJSSDKPayResult(transaction_id, out_trade_no);
			return payResult;
		}
		/**
		 * 获取微信公众号服务
		 * 
		 * @param wxid
		 * @return
		 */
		public WxMpService getWxMpService(String wxid) {
			WxMpConfigStorage config = getWxConfig(wxConfigService.fetch(wxid));
			WxMpService wxMpService = new WxMpServiceImpl();
			wxMpService.setWxMpConfigStorage(config);
			return wxMpService;
		}
		/**
		 * 获取公众号配置
		 * 
		 * @param appInfo
		 * @return
		 */
		public WxMpConfigStorage getWxConfig(Wx_config appInfo) {
			if (null == appInfo)
				return null;
			WxMpConfigStorage config = new WxMpInMemoryConfigStorage();
			((WxMpInMemoryConfigStorage) config).setAppId(appInfo.getAppid()); // 设置微信公众号的appid
			((WxMpInMemoryConfigStorage) config).setSecret(appInfo.getAppsecret()); // 设置微信公众号的app
			((WxMpInMemoryConfigStorage) config).setPartnerId(appInfo.getPartnerId()); // 设置微信支付商户号
			((WxMpInMemoryConfigStorage) config).setPartnerKey(appInfo.getPartnerKey()); // 设置微信支付商户号
			((WxMpInMemoryConfigStorage) config).setToken(appInfo.getToken()); // 设置微信公众号的token
			((WxMpInMemoryConfigStorage) config).setAesKey(appInfo.getEncodingAESKey()); // 设置微信公众号的EncodingAESKey

			return config;
		}
}
